package com.ruoyi.device.service.impl;

import java.util.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ruoyi.device.service.IStatisticsService;
import com.ruoyi.device.mapper.DeviceInfoMapper;
import com.ruoyi.device.mapper.StatisticsMapper;
import com.ruoyi.common.core.utils.poi.ExcelUtil;

/**
 * WiFi统计服务实现
 * 
 * @author ruoyi
 * @date 2025-09-12
 */
@Service
public class StatisticsServiceImpl implements IStatisticsService 
{
    @Autowired
    private DeviceInfoMapper deviceInfoMapper;
    
    @Autowired
    private StatisticsMapper statisticsMapper;

    @Override
    public Map<String, Object> getOverviewStatistics(String startDate, String endDate, String deviceName, String locationName) 
    {
        Map<String, Object> params = buildParams(startDate, endDate, deviceName, locationName);
        
        // 获取基础统计数据
        Map<String, Object> current = statisticsMapper.getOverviewData(params);
        
        // 获取昨日数据用于计算变化率
        Map<String, Object> yesterdayParams = buildYesterdayParams(startDate, endDate);
        Map<String, Object> yesterday = statisticsMapper.getOverviewData(yesterdayParams);
        
        Map<String, Object> result = new HashMap<>();
        
        // 当前数据
        result.put("totalConnections", getIntValue(current, "totalConnections"));
        result.put("activeUsers", getIntValue(current, "activeUsers"));
        result.put("avgDuration", getDoubleValue(current, "avgDuration"));
        result.put("successRate", getDoubleValue(current, "successRate"));
        
        // 计算变化率
        result.put("connectionChange", calculateChangeRate(current, yesterday, "totalConnections"));
        result.put("userChange", calculateChangeRate(current, yesterday, "activeUsers"));
        result.put("durationChange", calculateChangeRate(current, yesterday, "avgDuration"));
        result.put("rateChange", calculateChangeRate(current, yesterday, "successRate"));
        
        return result;
    }

    @Override
    public List<Map<String, Object>> getDeviceStatistics(String startDate, String endDate, String deviceName, String locationName) 
    {
        Map<String, Object> params = buildParams(startDate, endDate, deviceName, locationName);
        return statisticsMapper.getDeviceStatistics(params);
    }

    @Override
    public Map<String, Object> getConnectionChartData(String startDate, String endDate, String deviceId) 
    {
        Map<String, Object> params = new HashMap<>();
        if (StringUtils.hasText(startDate)) params.put("startDate", startDate);
        if (StringUtils.hasText(endDate)) params.put("endDate", endDate);
        if (StringUtils.hasText(deviceId)) params.put("deviceId", deviceId);
        
        List<Map<String, Object>> data = statisticsMapper.getConnectionTrendData(params);
        
        Map<String, Object> result = new HashMap<>();
        List<String> categories = new ArrayList<>();
        List<Integer> totalConnections = new ArrayList<>();
        List<Integer> successConnections = new ArrayList<>();
        List<Integer> failedConnections = new ArrayList<>();
        
        for (Map<String, Object> item : data) {
            categories.add(getString(item, "date"));
            totalConnections.add(getIntValue(item, "totalConnections"));
            successConnections.add(getIntValue(item, "successConnections"));
            failedConnections.add(getIntValue(item, "failedConnections"));
        }
        
        result.put("categories", categories);
        result.put("totalConnections", totalConnections);
        result.put("successConnections", successConnections);
        result.put("failedConnections", failedConnections);
        
        return result;
    }

    @Override
    public Map<String, Object> getDeviceStatusData() 
    {
        List<Map<String, Object>> data = statisticsMapper.getDeviceStatusData();
        
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> statusList = new ArrayList<>();
        
        for (Map<String, Object> item : data) {
            Map<String, Object> statusItem = new HashMap<>();
            statusItem.put("name", getStatusName(getIntValue(item, "status")));
            statusItem.put("value", getIntValue(item, "count"));
            statusList.add(statusItem);
        }
        
        result.put("data", statusList);
        return result;
    }

    @Override
    public Map<String, Object> getRegionChartData(String startDate, String endDate) 
    {
        Map<String, Object> params = new HashMap<>();
        if (StringUtils.hasText(startDate)) params.put("startDate", startDate);
        if (StringUtils.hasText(endDate)) params.put("endDate", endDate);
        
        List<Map<String, Object>> data = statisticsMapper.getRegionData(params);
        
        Map<String, Object> result = new HashMap<>();
        List<String> regions = new ArrayList<>();
        List<Integer> connections = new ArrayList<>();
        
        for (Map<String, Object> item : data) {
            regions.add(getString(item, "locationName"));
            connections.add(getIntValue(item, "connections"));
        }
        
        result.put("regions", regions);
        result.put("connections", connections);
        
        return result;
    }

    @Override
    public Map<String, Object> getHourChartData(String startDate, String endDate) 
    {
        Map<String, Object> params = new HashMap<>();
        if (StringUtils.hasText(startDate)) params.put("startDate", startDate);
        if (StringUtils.hasText(endDate)) params.put("endDate", endDate);
        
        List<Map<String, Object>> data = statisticsMapper.getHourData(params);
        
        Map<String, Object> result = new HashMap<>();
        List<String> hours = new ArrayList<>();
        List<Integer> connections = new ArrayList<>();
        
        for (Map<String, Object> item : data) {
            hours.add(getString(item, "hour") + ":00");
            connections.add(getIntValue(item, "connections"));
        }
        
        result.put("hours", hours);
        result.put("connections", connections);
        
        return result;
    }

    @Override
    public Map<String, Object> getDeviceDetailInfo(String deviceId, String startDate, String endDate) 
    {
        Map<String, Object> params = new HashMap<>();
        params.put("deviceId", deviceId);
        if (StringUtils.hasText(startDate)) params.put("startDate", startDate);
        if (StringUtils.hasText(endDate)) params.put("endDate", endDate);
        
        Map<String, Object> deviceInfo = statisticsMapper.getDeviceDetailInfo(params);
        List<Map<String, Object>> userStats = statisticsMapper.getDeviceUserStats(params);
        
        deviceInfo.put("userStats", userStats);
        
        return deviceInfo;
    }

    @Override
    public void exportStatistics(HttpServletResponse response, String startDate, String endDate, String deviceName, String locationName) 
    {
        Map<String, Object> params = buildParams(startDate, endDate, deviceName, locationName);
        List<Map<String, Object>> list = statisticsMapper.getDeviceStatistics(params);
        
        // 转换为导出格式
        List<Map<String, Object>> exportList = new ArrayList<>();
        for (Map<String, Object> item : list) {
            Map<String, Object> exportItem = new HashMap<>();
            exportItem.put("设备ID", getString(item, "deviceId"));
            exportItem.put("设备名称", getString(item, "deviceName"));
            exportItem.put("场所名称", getString(item, "locationName"));
            exportItem.put("连接次数", getIntValue(item, "connections"));
            exportItem.put("活跃用户", getIntValue(item, "activeUsers"));
            exportItem.put("平均时长", getDoubleValue(item, "avgDuration"));
            exportItem.put("成功率", getDoubleValue(item, "successRate") + "%");
            exportItem.put("最后活跃时间", getString(item, "lastActiveTime"));
            exportList.add(exportItem);
        }
        
        //ExcelUtil<Map<String, Object>> util = new ExcelUtil<Map<String, Object>>(Map.class);
        try {
          //  util.exportExcel(response, exportList, "设备统计数据");
        } catch (Exception e) {
            throw new RuntimeException("导出失败", e);
        }
    }

    // 辅助方法
    private Map<String, Object> buildParams(String startDate, String endDate, String deviceName, String locationName) {
        Map<String, Object> params = new HashMap<>();
        if (StringUtils.hasText(startDate)) params.put("startDate", startDate);
        if (StringUtils.hasText(endDate)) params.put("endDate", endDate);
        if (StringUtils.hasText(deviceName)) params.put("deviceName", deviceName);
        if (StringUtils.hasText(locationName)) params.put("locationName", locationName);
        return params;
    }

    private Map<String, Object> buildYesterdayParams(String startDate, String endDate) {
        Map<String, Object> params = new HashMap<>();
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            if (StringUtils.hasText(startDate)) {
                Date start = sdf.parse(startDate);
                Calendar cal = Calendar.getInstance();
                cal.setTime(start);
                cal.add(Calendar.DAY_OF_MONTH, -1);
                params.put("startDate", sdf.format(cal.getTime()));
            }
            if (StringUtils.hasText(endDate)) {
                Date end = sdf.parse(endDate);
                Calendar cal = Calendar.getInstance();
                cal.setTime(end);
                cal.add(Calendar.DAY_OF_MONTH, -1);
                params.put("endDate", sdf.format(cal.getTime()));
            }
        } catch (Exception e) {
            // 如果日期解析失败，返回空参数
        }
        return params;
    }

    private Double calculateChangeRate(Map<String, Object> current, Map<String, Object> yesterday, String key) {
        Double currentValue = getDoubleValue(current, key);
        Double yesterdayValue = getDoubleValue(yesterday, key);
        
        if (yesterdayValue == null || yesterdayValue == 0) {
            return 0.0;
        }
        
        BigDecimal change = new BigDecimal((currentValue - yesterdayValue) / yesterdayValue * 100);
        return change.setScale(1, RoundingMode.HALF_UP).doubleValue();
    }

    private String getStatusName(Integer status) {
        if (status == null) return "未知";
        switch (status) {
            case 0: return "离线";
            case 1: return "在线";
            case 2: return "故障";
            default: return "未知";
        }
    }

    private Integer getIntValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return 0;
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        try {
            return Integer.valueOf(value.toString());
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    private Double getDoubleValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return 0.0;
        if (value instanceof Number) {
            return ((Number) value).doubleValue();
        }
        try {
            return Double.valueOf(value.toString());
        } catch (NumberFormatException e) {
            return 0.0;
        }
    }

    private String getString(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value == null ? "" : value.toString();
    }
} 